// ============================================================================ // Tabber.cpp // ============================================================================ // Copyright (c) WildPackets, Inc. 2000-2003. All rights reserved. #include "StdAfx.h" #include "PluginDebug.h" #include "MemUtil.h" #include "Resource.h" #include "Tabber.h" #import "msflxgrd.ocx" no_namespace #define kTabberWndClass _T("TabberWndClass") IMPLEMENT_PLUGIN(CTabberPlugin) // Static class members. PluginID CTabberPlugin::s_ID = {0xF968637D,0x861F,0x4F8D,{0xB3,0x6F,0xF3,0xC0,0xE3,0xB3,0xDF,0x5E}}; UInt32 CTabberPlugin::s_ParentArray[] = { 1400, // TCP over any carrier protocol }; UInt32 CTabberPlugin::s_ParentCount = COUNTOF(s_ParentArray); WNDCLASSEX CTabberPlugin::s_WndClass; bool CTabberPlugin::s_bRegistered = false; // ---------------------------------------------------------------------------- // GetName // ---------------------------------------------------------------------------- void CTabberPlugin::GetName( TCHAR* outName ) const { // Get the plugin name. LoadString( 128, outName ); } // ---------------------------------------------------------------------------- // GetSupportedProtoSpecs // ---------------------------------------------------------------------------- void CTabberPlugin::GetSupportedProtoSpecs( UInt32* outNumProtoSpecs, UInt32** outProtoSpecs ) const { *outNumProtoSpecs = s_ParentCount; *outProtoSpecs = s_ParentArray; } // ----------------------------------------------------------------------------- // Load // ----------------------------------------------------------------------------- int CTabberPlugin::Load( PluginLoadParam* ioParams ) { if ( CPeekPlugin::Load( ioParams ) != PLUGIN_RESULT_SUCCESS ) { return -1; } // Register our window class. memset( &s_WndClass, 0, sizeof(WNDCLASSEX) ); s_WndClass.cbSize = sizeof(WNDCLASSEX); s_WndClass.style = CS_GLOBALCLASS; s_WndClass.lpfnWndProc = MyWndProc; s_WndClass.hInstance = GetResourceHandle(); s_WndClass.hbrBackground = (HBRUSH) COLOR_BACKGROUND; s_WndClass.lpszClassName = kTabberWndClass; s_WndClass.cbWndExtra = 8; // 8 bytes extra per window. if ( ::RegisterClassEx( &s_WndClass ) != 0 ) { s_bRegistered = true; } return PLUGIN_RESULT_SUCCESS; } // ---------------------------------------------------------------------------- // Unload // ---------------------------------------------------------------------------- int CTabberPlugin::Unload() { if ( s_bRegistered ) { // Unregister our window class. ::UnregisterClass( kTabberWndClass, GetResourceHandle() ); } // Call inherited. return CPeekPlugin::Unload(); } // ---------------------------------------------------------------------------- // CreateContext // ---------------------------------------------------------------------------- int CTabberPlugin::CreateContext( PluginCreateContextParam* ioParams ) { // Allocate context. STabberPluginContext* pContext = new STabberPluginContext; // Remember app context. pContext->captureContext = ioParams->fCaptureContext; // Clear all stats. pContext->SynCount = 0; pContext->FinCount = 0; pContext->pTabControl = NULL; pContext->hTabWnd = NULL; pContext->bDoAnalysis = false; // Give context to host. *(ioParams->fContextPtr) = pContext; // Make an ActiveX tab. if ( DoAddTab( m_pAppContextData, pContext->captureContext, _T("Tabber"), _T("MSFlexGridLib.MSFlexGrid"), (void**) &pContext->pTabControl ) == PLUGIN_RESULT_SUCCESS ) { PLUGIN_ASSERT( pContext->pTabControl != NULL ); HRESULT hr; IMSFlexGrid* pFlexGrid; hr = pContext->pTabControl->QueryInterface( __uuidof(IMSFlexGrid), (void**) &pFlexGrid ); if ( SUCCEEDED(hr) ) { int nRows = 3; int nCols = 2; // Set the number of columns and rows. pFlexGrid->Cols = nCols; pFlexGrid->Rows = nRows; // Make all rows and columns bold. for ( int i = 0; i < nRows; i++ ) { pFlexGrid->Row = i; pFlexGrid->Col = 0; pFlexGrid->CellFontBold = TRUE; pFlexGrid->CellFontName = _T("Arial"); } for ( int j = 0; j < nCols; j++ ) { pFlexGrid->Row = 0; pFlexGrid->Col = j; pFlexGrid->CellFontBold = TRUE; pFlexGrid->CellFontName = _T("Arial"); } // Set up row and column headings. pFlexGrid->TextMatrix[0][0] = _T("Stat"); pFlexGrid->TextMatrix[0][1] = _T("Value"); pFlexGrid->TextMatrix[1][0] = _T("TCP SYNs"); pFlexGrid->TextMatrix[2][0] = _T("TCP FINs"); for ( int k = 1; k < nRows; k++ ) { pFlexGrid->Row = k; pFlexGrid->Col = 1; pFlexGrid->CellFontName = _T("Arial"); pFlexGrid->TextMatrix[k][1] = _T("0"); } pFlexGrid->Row = 1; pFlexGrid->Col = 1; } } // Make a WNDCLASS-based tab. if ( ( ioParams->fContextFlags == kContextType_CaptureWindow ) || ( ioParams->fContextFlags == kContextType_FileWindow ) ) { DoAddTab( m_pAppContextData, pContext->captureContext, ioParams->fContextFlags == kContextType_CaptureWindow ? _T("Capture Tab") : _T("File Tab"), kTabberWndClass, (void**) &pContext->hTabWnd ); PLUGIN_ASSERT( pContext->hTabWnd != NULL ); // Store data in the window. Index 0 gets the context. SetWindowLong( pContext->hTabWnd, 0, (LONG) pContext ); // Index 1 gets the this. SetWindowLong( pContext->hTabWnd, 4, (LONG) this ); } return PLUGIN_RESULT_SUCCESS; } // ---------------------------------------------------------------------------- // DisposeContext // ---------------------------------------------------------------------------- int CTabberPlugin::DisposeContext( PluginDisposeContextParam* ioParams ) { STabberPluginContext* pContext = (STabberPluginContext*) (ioParams->fContext); if ( pContext == NULL ) return -1; delete pContext; return PLUGIN_RESULT_SUCCESS; } // ---------------------------------------------------------------------------- // ProcessPacket // ---------------------------------------------------------------------------- int CTabberPlugin::ProcessPacket( PluginProcessPacketParam* ioParams ) { // Get the data start. UInt16 nTcpBytes = 0; const UInt8* pTcpHdr; int iRetVal = GetTCPUDPInfo( ioParams->fPacket->fProtoSpec, ioParams->fPacket, ioParams->fPacketData, ioParams->fMediaType, ioParams->fMediaSubType, &pTcpHdr, &nTcpBytes, NULL, NULL, NULL ); if ( iRetVal == PLUGIN_RESULT_SUCCESS && (pTcpHdr != NULL) && (nTcpBytes >= 16) ) { // Get the TCP Flags UInt8 TcpFlags = pTcpHdr[13]; // Get the context. STabberPluginContext* pContext = (STabberPluginContext*) ioParams->fContext; if ( pContext == NULL ) return -1; if ( (TcpFlags & 0x01) != 0 ) { pContext->FinCount++; } if ( (TcpFlags & 0x02) != 0 ) { pContext->SynCount++; } } return PLUGIN_RESULT_SUCCESS; } // ---------------------------------------------------------------------------- // GetPacketString // ---------------------------------------------------------------------------- int CTabberPlugin::GetPacketString( PluginGetPacketStringParam* ioParams ) { // Get the context. STabberPluginContext* pContext = (STabberPluginContext*) ioParams->fContext; if ( pContext == NULL ) return -1; // Get and format dest physical address. UInt8 physDest[16]; UInt16 nPhysDestType; TCHAR szPhysDest[256]; UInt8 nHostType; DoPacketGetAddress( m_pAppContextData, pContext->captureContext, kAddressType_DestPhysical, ioParams->fMediaType, ioParams->fMediaSubType, ioParams->fPacket, ioParams->fPacketData, ioParams->fPacketNumber, physDest, &nPhysDestType ); DoLookupName( (UInt8*) physDest, nPhysDestType, szPhysDest, &nHostType ); // Get and format src physical address. UInt8 physSrc[16]; UInt16 nPhysSrcType; TCHAR szPhysSrc[256]; DoPacketGetAddress( m_pAppContextData, pContext->captureContext, kAddressType_SrcPhysical, ioParams->fMediaType, ioParams->fMediaSubType, ioParams->fPacket, ioParams->fPacketData, ioParams->fPacketNumber, physSrc, &nPhysSrcType ); DoLookupName( (UInt8*) physSrc, nPhysSrcType, szPhysSrc, &nHostType ); // Now format string _stprintf( ioParams->fString, _T("%s->%s"), szPhysSrc, szPhysDest ); return (ioParams->fString[0] != 0) ? PLUGIN_RESULT_SUCCESS : -1; } // ---------------------------------------------------------------------------- // GetPacketAnalysis // ---------------------------------------------------------------------------- int CTabberPlugin::GetPacketAnalysis( PluginGetPacketStringParam* ioParams ) { // Get the context. STabberPluginContext* pContext = (STabberPluginContext*) ioParams->fContext; if ( pContext == NULL ) return -1; // Get and format dest logical address. UInt8 logDest[16]; UInt16 nLogDestType; TCHAR szLogDest[256]; UInt8 nHostType; DoPacketGetAddress( m_pAppContextData, pContext->captureContext, kAddressType_DestLogical, ioParams->fMediaType, ioParams->fMediaSubType, ioParams->fPacket, ioParams->fPacketData, ioParams->fPacketNumber, logDest, &nLogDestType ); DoLookupName( (UInt8*) logDest, nLogDestType, szLogDest, &nHostType ); // Get and format src logical address. UInt8 logSrc[16]; UInt16 nLogSrcType; TCHAR szLogSrc[256]; DoPacketGetAddress( m_pAppContextData, pContext->captureContext, kAddressType_SrcLogical, ioParams->fMediaType, ioParams->fMediaSubType, ioParams->fPacket, ioParams->fPacketData, ioParams->fPacketNumber, logSrc, &nLogSrcType ); DoLookupName( (UInt8*) logSrc, nLogSrcType, szLogSrc, &nHostType ); // Now format string _stprintf( ioParams->fString, _T("%s->%s"), szLogSrc, szLogDest ); return (ioParams->fString[0] != 0) ? PLUGIN_RESULT_SUCCESS : -1; } // ---------------------------------------------------------------------------- // Reset // ---------------------------------------------------------------------------- int CTabberPlugin::Reset( PluginResetParam* ioParams ) { // Get the context. STabberPluginContext* pContext = (STabberPluginContext*) ioParams->fContext; if ( pContext == NULL ) return -1; // Clear all stats. pContext->SynCount = 0; pContext->FinCount = 0; if ( pContext->pTabControl != NULL ) { HRESULT hr; IMSFlexGrid* pFlexGrid; hr = pContext->pTabControl->QueryInterface( __uuidof(IMSFlexGrid), (void**) &pFlexGrid ); if ( SUCCEEDED(hr) ) { pFlexGrid->TextMatrix[1][1] = _T("0"); pFlexGrid->TextMatrix[2][1] = _T("0"); } } DoSummaryModifyEntry( m_pAppContextData, pContext->captureContext, kTCPSynCount, kSumStatsGroupName, kPluginSummarySize_UInt64 | kPluginSummaryType_PacketCount, &pContext->SynCount ); DoSummaryModifyEntry( m_pAppContextData, pContext->captureContext, kTCPFinCount, kSumStatsGroupName, kPluginSummarySize_UInt64 | kPluginSummaryType_PacketCount, &pContext->FinCount ); return PLUGIN_RESULT_SUCCESS; } // ---------------------------------------------------------------------------- // Summary // ---------------------------------------------------------------------------- int CTabberPlugin::Summary( PluginSummaryParam* ioParams ) { // Get the context. STabberPluginContext* pContext = (STabberPluginContext*) ioParams->fContext; if ( pContext == NULL ) return -1; if ( pContext->pTabControl != NULL ) { HRESULT hr; IMSFlexGrid* pFlexGrid; hr = pContext->pTabControl->QueryInterface( __uuidof(IMSFlexGrid), (void**) &pFlexGrid ); if ( SUCCEEDED(hr) ) { TCHAR szString[256]; _ui64tot( pContext->SynCount, szString, 10 ); pFlexGrid->TextMatrix[1][1] = szString; _ui64tot( pContext->FinCount, szString, 10 ); pFlexGrid->TextMatrix[2][1] = szString; } } DoSummaryModifyEntry( m_pAppContextData, pContext->captureContext, kTCPSynCount, kSumStatsGroupName, kPluginSummarySize_UInt64 | kPluginSummaryType_PacketCount, &pContext->SynCount ); DoSummaryModifyEntry( m_pAppContextData, pContext->captureContext, kTCPFinCount, kSumStatsGroupName, kPluginSummarySize_UInt64 | kPluginSummaryType_PacketCount, &pContext->FinCount ); return PLUGIN_RESULT_SUCCESS; } // ---------------------------------------------------------------------------- // Apply // ---------------------------------------------------------------------------- int CTabberPlugin::Apply( PluginApplyParam* /*ioParams*/ ) { // We only get packets which match the ProtoSpecs we've requested // on load, so we trust this is a packet we want. return PLUGIN_RESULT_SUCCESS; } // ---------------------------------------------------------------------------- // Select // ---------------------------------------------------------------------------- int CTabberPlugin::Select( PluginSelectParam* /*ioParams*/ ) { // We only get packets which match the ProtoSpecs we've requested // on load, so we trust this is a packet we want. return PLUGIN_RESULT_SUCCESS; } // ---------------------------------------------------------------------------- // Filter // ---------------------------------------------------------------------------- int CTabberPlugin::Filter( PluginFilterParam* ioParams ) { // We only get packets which match the ProtoSpecs we've requested // on load, so we trust this is a packet we want. ioParams->fBytesAccepted = PLUGIN_ACCEPT_WHOLE_PACKET; return PLUGIN_RESULT_SUCCESS; } // ---------------------------------------------------------------------------- // About // ---------------------------------------------------------------------------- int CTabberPlugin::About() { // Show the about dialog. ::DialogBox( GetResourceHandle(), MAKEINTRESOURCE(IDD_ABOUT), ::GetForegroundWindow(), (DLGPROC) AboutDialogProc ); return PLUGIN_RESULT_SUCCESS; } // ---------------------------------------------------------------------------- // NameTableUpdate // ---------------------------------------------------------------------------- int CTabberPlugin::NameTableUpdate( PluginNameTableUpdateParam* ioParams ) { // STabberPluginContext* pContext = (STabberPluginContext*) ioParams->fContext; // if( pContext == NULL ) return -1; TCHAR szMessage[256]; _stprintf( szMessage, _T("NameTableUpdate: %s"), ioParams->fEntry->fName ); DoNotify( m_pAppContextData, NULL, 0, kNotifySeverity_Informational, szMessage, NULL ); return PLUGIN_RESULT_SUCCESS; } // ---------------------------------------------------------------------------- // AboutDialogProc // ---------------------------------------------------------------------------- BOOL CALLBACK CTabberPlugin::AboutDialogProc( HWND inDialogH, UINT inMessage, WPARAM inWParam, LPARAM /*inLParam*/ ) { switch ( inMessage ) { case WM_INITDIALOG: { return TRUE; } break; case WM_COMMAND: { switch ( LOWORD(inWParam) ) { case IDOK: { // Close the dialog. ::EndDialog( inDialogH, TRUE ); return TRUE; } break; case IDCANCEL: { // Close the dialog. ::EndDialog( inDialogH, TRUE ); return TRUE; } break; } } break; } return FALSE; } // ----------------------------------------------------------------------------- // MyWndProc // ----------------------------------------------------------------------------- LRESULT CALLBACK CTabberPlugin::MyWndProc( HWND inWnd, UINT inMessage, WPARAM inWParam, LPARAM inLParam ) { switch( inMessage ) { case WM_CREATE: { // Select button. CreateWindow( _T("BUTTON"), _T("Select"), WS_VISIBLE | WS_CHILD | BS_PUSHBUTTON, 10, 10, 60, 20, inWnd, (HMENU) ID_SELECT, (HINSTANCE) GetWindowLong( inWnd, GWL_HINSTANCE), NULL ); // Update button CreateWindow( _T("BUTTON"), _T("Update"), WS_VISIBLE | WS_CHILD | BS_PUSHBUTTON, 80, 10, 60, 20, inWnd, (HMENU) ID_UPDATE, (HINSTANCE) GetWindowLong( inWnd, GWL_HINSTANCE), NULL ); // Name button CreateWindow( _T("BUTTON"), _T("Name"), WS_VISIBLE | WS_CHILD | BS_PUSHBUTTON, 150, 10, 60, 20, inWnd, (HMENU) ID_NAME, (HINSTANCE) GetWindowLong( inWnd, GWL_HINSTANCE), NULL ); // Resolve button CreateWindow( _T("BUTTON"), _T("Resolve"), WS_VISIBLE | WS_CHILD | BS_PUSHBUTTON, 220, 10, 60, 20, inWnd, (HMENU) ID_RESOLVE, (HINSTANCE) GetWindowLong( inWnd, GWL_HINSTANCE), NULL ); // Filter button CreateWindow( _T("BUTTON"), _T("Filter"), WS_VISIBLE | WS_CHILD | BS_PUSHBUTTON, 290, 10, 60, 20, inWnd, (HMENU) ID_FILTER, (HINSTANCE) GetWindowLong( inWnd, GWL_HINSTANCE), NULL ); return 0; } break; case WM_PAINT: { RECT r; GetClientRect( inWnd, &r ); PAINTSTRUCT ps; HDC myDc = BeginPaint( inWnd, &ps); Ellipse( myDc, r.left, r.top, r.right, r.bottom ); EndPaint( inWnd, &ps ); return 0; } break; case WM_COMMAND: { switch( LOWORD( inWParam ) ) { case ID_SELECT: { // Get the context. STabberPluginContext* pContext = (STabberPluginContext*) GetWindowLong( inWnd, 0 ); // Get the Plugin. CTabberPlugin* pPlugin = (CTabberPlugin*) GetWindowLong( inWnd, 4 ); // Select packets from/to an 192.216.124.120. const UInt8 nIPAddr[4] = { 0xC0, 0xD8, 0x7C, 0x78 }; CPeekPlugin::DoSelectPacketsEx( pPlugin->m_pAppContextData, pContext->captureContext, (const UInt8*) &nIPAddr, kEntryType_IPAddr, NULL, 0, 0, 0, kEntryType_IPPort, true, 0 ); return true; } break; case ID_UPDATE: { // Get the context. STabberPluginContext* pContext = (STabberPluginContext*) GetWindowLong( inWnd, 0 ); pContext->bDoAnalysis = true; // Get the Plugin. CTabberPlugin* pPlugin = (CTabberPlugin*) GetWindowLong( inWnd, 4 ); // Claim some packets. UInt64 nPackets[] = { 3, 5, 7, 9, 11 }; UInt32 nPacketCount = COUNTOF( nPackets ); // Need context here! for( UInt32 x = 0; x < nPacketCount; x++ ) { UInt64 nPacket = nPackets[x]; CPeekPlugin::DoClaimPacketString( pPlugin->m_pAppContextData, pContext->captureContext, nPacket, true ); } return true; } break; case ID_NAME: { // Insert into name table 192.216.124.120. UInt8 nIPAddr[4] = { 0xC0, 0xD8, 0x7C, 0x78 }; TCHAR* pszName = _T("morpheus.wildpackets.com"); PluginNameTableEntry theEntry; theEntry.fColor = RGB( 0, 0, 0 ); theEntry.fEntry = (UInt8*) &nIPAddr; theEntry.fEntryType = kEntryType_IPAddr; theEntry.fGroup = NULL; theEntry.fHostType = kHostType_Workstation; theEntry.fName = pszName; CPeekPlugin::DoInvokeNameEditDialog( &theEntry ); return true; } break; case ID_RESOLVE: { // Resolve 192.216.124.79 UInt8 nIPAddr[4] = { 0xC0, 0xD8, 0x7C, 0x4F }; CPeekPlugin::DoResolveAddress( nIPAddr, kEntryType_IPAddr ); return true; } break; case ID_FILTER: { // Filter for 192.216.124.1 <-> 192.216.124.79, port 80 <-> any. UInt8 nSrcIPAddr[4] = { 0xC0, 0xD8, 0x7C, 0x01 }; UInt8 nDstIPAddr[4] = { 0xC0, 0xD8, 0x7C, 0x78 }; CPeekPlugin::DoMakeFilter( nSrcIPAddr, kEntryType_IPAddr, nDstIPAddr, kEntryType_IPAddr, NETWORKTOHOST16( (UInt16) 80 ), 0, kEntryType_IPPort, true ); return true; } break; } } break; } return DefWindowProc( inWnd, inMessage, inWParam, inLParam ); }